//
//  Keychain.swift
//  FlameB
//
//  Created by 连俊 on 2020/7/28.
//  Copyright © 2020 连俊. All rights reserved.
//

import Foundation
import Security

class User: NSObject, NSCoding {
    var userId: String
    var token: String
    
    init(_ userId: String ,_ token: String) {
        self.userId = userId
        self.token = token
    }
    
    required convenience init?(coder decoder: NSCoder) {
        guard let userId = decoder.decodeObject(forKey: "userId") as? String,
            let token = decoder.decodeObject(forKey:"token") as? String else {
                return nil
        }
        self.init(userId, token)
    }
    
    func encode(with coder: NSCoder) {
        coder.encode(self.userId, forKey: "userId")
        coder.encode(self.token, forKey: "token")
    }
    
    func saveToKC() {
        let data = NSKeyedArchiver.archivedData(withRootObject: self)
        _ = Keychain.save(key: "User", data: data)
    }
    
    class func loadFromKC()-> User? {
        let data = Keychain.load(key: "User")
        guard let aData = data else {return nil}
        return  NSKeyedUnarchiver.unarchiveObject(with: aData) as? User
    }
    
    class func clearKC() {
        _ = Keychain.delete(key: "User")
    }
}

class Keychain {
    class func save(key: String, data: Data) -> Bool {
        let query = [
            kSecClass as String         : kSecClassGenericPassword as String,
            kSecAttrAccount as String   : key,
            kSecValueData as String     : data
        ] as [String : Any]
        SecItemDelete(query as CFDictionary)
        let status: OSStatus = SecItemAdd(query as CFDictionary, nil)
        return status == noErr
    }
    class func load(key: String) -> Data? {
        let query = [
            kSecClass as String       : kSecClassGenericPassword,
            kSecAttrAccount as String : key,
            kSecReturnData as String  : kCFBooleanTrue ?? true,
            kSecMatchLimit as String  : kSecMatchLimitOne ] as [String : Any]
        var dataTypeRef: AnyObject?
        let status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }
        
        if status == errSecSuccess {
            if let data = dataTypeRef as! Data? {
                return data
            }
        }
        return nil
    }
    class func delete(key: String) -> Bool {
        let query = [
            kSecClass as String       : kSecClassGenericPassword,
            kSecAttrAccount as String : key ] as [String : Any]
        
        let status: OSStatus = SecItemDelete(query as CFDictionary)
        return status == noErr
    }
    class func clear() -> Bool {
        let query = [ kSecClass as String : kSecClassGenericPassword ]
        let status: OSStatus = SecItemDelete(query as CFDictionary)
        return status == noErr
    }
}
